from sample.extra_process.spot import SPOT
from sample.config.global_data import spot_q, spot_level, median_diff_threhold
import numpy as np

# 使用spot算法得到异常分数的阈值


def spot(kpi, spot_data, init_data, low_expectation, high_expectation, median_diff, item_name):
    try:
        s = SPOT(q=spot_q)
        s.fit(init_data=init_data, data=spot_data)
        s.initialize(level=spot_level, verbose=False)
        res = s.run(with_alarm=True)
        thresholds = res['thresholds']
        eval_label = [0] * len(spot_data)
        for index in range(len(eval_label)):
            if index in res['alarms'] and (kpi.raw_values[index] > high_expectation[index] or kpi.raw_values[index] < low_expectation[index])\
                    and median_diff[index] > median_diff_threhold[item_name]:
                eval_label[index] = 1
    except:
        thresholds = [-1 for _ in spot_data]
        eval_label = [-1 for _ in spot_data]
    return thresholds, eval_label


def filter_by_median_diff(item_name, kpi):
    # 中位差地窗口大小
    omega = 10
    threshold = median_diff_threhold[item_name]
    v_list = kpi.values
    c_list = []
    # 是否要继续分析
    res = False
    for index in range(len(kpi.values)):
        if omega <= index <= len(kpi.values)-omega:
            c = median_diff(v_list=v_list, index=index, omega=omega)
            c_list.append(c)
            if c > threshold:
                res = True
        else:
            c_list.append(0)
    return res, c_list


def median_diff(v_list, index, omega):
    x_before = v_list[index-omega+1:index+1]
    median_before = np.median(x_before)
    x_after = v_list[index+1:index+omega+1]
    median_after = np.median(x_after)
    return np.abs(median_before-median_after)
